package com.tiancheng.trade.merchant.configuration;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 将请求参数下划线转驼峰
 */
@Component
public class UnderlineToCamelArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        String method = methodParameter.getMethod().getName();
        Class<?> ptype = methodParameter.getParameterType();
        boolean isPrimitive = CharSequence.class.isAssignableFrom(ptype) || Number.class.isAssignableFrom(ptype);
        return !isPrimitive && (
                StringUtils.startsWith(method, "find") || StringUtils.startsWith(method, "query")
                        || StringUtils.startsWith(method, "get"));
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        return handleParameterNames(parameter, webRequest);
    }

    private Object handleParameterNames(MethodParameter parameter, NativeWebRequest webRequest) throws JsonProcessingException {

        Map<String, Object> param = new HashMap<>();
        Iterator<String> paramNames = webRequest.getParameterNames();
        while (paramNames.hasNext()) {
            String paramName = paramNames.next();
            Object o = webRequest.getParameter(paramName);
            param.put(paramName, o);
        }
        String json = objectMapper.writeValueAsString(param);
        return objectMapper.readValue(json, parameter.getParameterType());

    }

}
